/*
 * 
 * LegendShop 多用户商城系统
 * 
 *  版权所有,并保留所有权利。
 * 
 */
package com.legendshop.code;

import java.io.File;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.legendshop.code.config.Config;
import com.legendshop.code.freemarker.AbstractBulidTemplet;
import com.legendshop.code.freemarker.BulidTemplet;
import com.legendshop.code.freemarker.builder.ControllerFileBulidTemplet;
import com.legendshop.code.freemarker.builder.DaoFileBulidTemplet;
import com.legendshop.code.freemarker.builder.DaoImplFileBulidTemplet;
import com.legendshop.code.freemarker.builder.EntityFileBulidTemplet;
import com.legendshop.code.freemarker.builder.HibernateEntityXmlBulidTemplet;
import com.legendshop.code.freemarker.builder.JspEntityListPageBulidTemplet;
import com.legendshop.code.freemarker.builder.JspEntityPageBulidTemplet;
import com.legendshop.code.freemarker.builder.MapperBulidTemplet;
import com.legendshop.code.freemarker.builder.SQLStatementBulidTemplet;
import com.legendshop.code.freemarker.builder.ServiceFileBulidTemplet;
import com.legendshop.code.freemarker.builder.ServiceImplFileBulidTemplet;
import com.legendshop.code.freemarker.builder.SpringConfigFileBulidTemplet;

public class SourceGen {
	private final static Logger logger = LoggerFactory.getLogger(AbstractBulidTemplet.class);
	
	private static final String ABS_PATH = SourceGen.class.getResource("/").getPath();
	
	private static final String BUILDER_PATH = "com/legendshop/code/freemarker/builder/";
	
	/**
	 * The main method.
	 *
	 * @param args the args
	 */
	public static void main(String[] args){
		logger.info("Create LegendShop source code starting !");
		List<Class<?>> list = new ArrayList<Class<?>>();
		try{
//			boolean recursive = true;
//			String pkg = "com.legendshop.code.freemarker.builder";
//			list = PackageUtil.getClassList(pkg, recursive, Templet.class);
			
			list = buildTemplet();
			
			SourceGen.exec(list);
		}catch(Exception e){
			logger.error("SourceGen error:",e);
		}
		logger.info("Create LegendShop source code  end!");
	}
	
	private static  List<Class<?>> buildTemplet(){
		List<Class<?>> list = new ArrayList<Class<?>>();
		list.add(ControllerFileBulidTemplet.class);
		list.add(DaoFileBulidTemplet.class);
		list.add(DaoImplFileBulidTemplet.class);
		list.add(EntityFileBulidTemplet.class);
		list.add(HibernateEntityXmlBulidTemplet.class);
		list.add(JspEntityListPageBulidTemplet.class);
		list.add(JspEntityPageBulidTemplet.class);
		list.add(MapperBulidTemplet.class);
		list.add(ServiceFileBulidTemplet.class);
		list.add(ServiceImplFileBulidTemplet.class);
		list.add(SpringConfigFileBulidTemplet.class);
		list.add(SQLStatementBulidTemplet.class);
		return list;
	}
	
	/**
	 * 遍历生成相关的模板文件
	 * @param list
	 * @throws Exception
	 */
	protected static void exec(List<Class<?>> list){
		String[] tables = Config.getInstance().getTableList();
		if(tables == null || tables.length == 0){
			logger.warn("No assign table name");
		}
		if(list == null || list.size() == 0){
			logger.warn("No templet builder");
		}
		for(String table:tables){
			for(Class<?> clazz : list){
				BulidTemplet bulidTemplet = null;
				try {
					bulidTemplet = (BulidTemplet)clazz.newInstance();
				} catch (InstantiationException e) {
					logger.error("InstantiationException :",e);
					return;
				} catch (IllegalAccessException e) {
					logger.error("IllegalAccessException :",e);
					return;
				}
				bulidTemplet.buildSourceFile(table);
			}
		}
	}

	
	/**
	 * 找到BulidTemplet接口的所有非抽象实现类
	 * @param list
	 * @param path
	 * @return
	 * @throws Exception
	 */
	protected static List<Class<?>> getTempletClass(List<Class<?>> list,String path) 
			throws Exception{
		if(path.contains(".svn")){
			return list;
		}
		File[] files = new File(path).listFiles();
		
		if(files != null){
			for(File file:files){
				if(file.isDirectory()){
					getTempletClass(list,path + file.getName() + "/");
				}else{
					String className = path.replace(ABS_PATH, "").replace("/", ".") + file.getName();
					className = className.substring(0, className.length()-6);
					Class<?> clazz = Thread.currentThread().getContextClassLoader().loadClass(className);
					if (!Modifier.isAbstract(clazz.getModifiers())
							&& Modifier.isPublic(clazz.getModifiers())
							&& (clazz.newInstance() instanceof BulidTemplet)) {
						list.add(clazz);
					}
				}
			}
		}
		return list;
	}
	
}